home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9006.ZIP / SCHULMAN.LST < prev    next >
File List  |  1990-05-02  |  11KB  |  393 lines

  1. _EXAMINING INSTANT-C_
  2. by Andrew Schulman
  3.  
  4. [LISTING ONE]
  5.  
  6. ;       protmode.asm -- 286 protected-mode instructions
  7. ;       requires MASM 5.0 or higher or TASM
  8. ;       masm -ml protmode; 
  9. ;       or, tasm -ml protmode;
  10.  
  11.         dosseg
  12.  
  13.         .286p
  14.         .model large
  15.         .code 
  16.  
  17.         public  _lsl, _lar, _verr, _verw, _sgdt, _sidt, _sldt
  18.  
  19. ;       extern unsigned far lsl(unsigned short sel);
  20. ;       input:   selector
  21. ;       output:  if valid and visible at current protection level,
  22. ;                   return segment limit (which is 0 for 1-byte seg!)
  23. ;                else
  24. ;                   return 0
  25. ;
  26. _lsl    proc
  27.         enter   0, 0
  28.         sub     ax, ax
  29.         lsl     ax, [bp+6]
  30.         leave
  31.         ret
  32. _lsl    endp
  33.  
  34. ;       extern unsigned short far lar(unsigned short sel);
  35. ;       input:   selector
  36. ;       output:  if valid and visible at current protection level,
  37. ;                   return access rights (which will never be 0)
  38. ;                else
  39. ;                   return 0
  40. ;
  41. _lar    proc
  42.         enter   0, 0
  43.         sub     ax, ax
  44.         lar     ax, [bp+6]
  45.         shr     ax, 8
  46.         leave       
  47.         ret
  48. _lar    endp
  49.  
  50. ;       extern BOOL far verr(unsigned short sel);
  51. ;       input:   selector
  52. ;       output:  valid for reading ? 1 : 0
  53. ;
  54. _verr   proc
  55.         enter   0, 0
  56.         mov     ax, 1
  57.         verr    word ptr [bp+6]
  58.         je      short verr_okay
  59.         dec     ax
  60. verr_okay:
  61.         leave                           
  62.         ret
  63. _verr   endp
  64.  
  65. ;       extern BOOL far verw(unsigned short sel);
  66. ;       input:   selector
  67. ;       output:  valid for writing ? 1 : 0
  68. ;
  69. _verw   proc
  70.         enter   0, 0
  71.         mov     ax, 1
  72.         verw    word ptr [bp+6]
  73.         je      short verw_okay
  74.         dec     ax
  75. verw_okay:
  76.         leave                           
  77.         ret
  78. _verw   endp
  79.  
  80. ;       extern void far sgdt(void far *gdt);
  81. ;       input:   far ptr to 6-byte structure
  82. ;       output:  fills structure with GDTR
  83. ;
  84. _sgdt   proc
  85.         enter 0, 0
  86.         les   bx, dword ptr [bp+6]          
  87.         sgdt  fword ptr es:[bx]
  88.         leave
  89.         ret
  90. _sgdt   endp
  91.  
  92. ;       extern void far sidt(void far *idt);
  93. ;       input:   far ptr to 6-byte structure
  94. ;       output:  fills structure with IDTR
  95. ;
  96. _sidt   proc
  97.         enter 0, 0
  98.         les   bx, dword ptr [bp+6]
  99.         sidt  fword ptr es:[bx]
  100.         leave
  101.         ret
  102. _sidt   endp
  103.  
  104. ;
  105. ;       extern unsigned short sldt(void);
  106. ;       input:   none
  107. ;       output:  Local Descriptor Table register (LDTR)
  108. ;
  109. _sldt   proc
  110.         sldt  ax
  111.         ret
  112. _sldt   endp
  113.  
  114.         end
  115.  
  116.  
  117.  
  118. [LISTING TWO]
  119.  
  120. /* PROTMODE.H */
  121. typedef enum { FALSE, TRUE } BOOL;
  122. #ifdef InstantC
  123. unsigned far lsl(unsigned short sel)        {extern;}
  124. unsigned short far lar(unsigned short sel)  {extern;}
  125. BOOL far verr(unsigned short sel)           {extern;}
  126. BOOL far verw(unsigned short sel)           {extern;}
  127. void far sgdt(void far *gdt)                {extern;}
  128. void far sidt(void far *idt)                {extern;}
  129. unsigned short sldt(void)                   {extern;}   
  130. #else
  131. extern unsigned far lsl(unsigned short sel);
  132. extern unsigned short far lar(unsigned short sel);
  133. extern BOOL far verr(unsigned short sel);
  134. extern BOOL far verw(unsigned short sel);
  135. extern void far sgdt(void far *gdt);
  136. extern void far sidt(void far *idt);
  137. extern unsigned short sldt(void);
  138. #endif
  139.  
  140.  
  141. [LISTING THREE]
  142.  
  143. /* BROWSE.C */
  144.  
  145. #ifdef InstantC
  146. #loadobj "protmode.obj"
  147. #endif
  148. #include "protmode.h"
  149.  
  150. void browse()
  151. {
  152.     unsigned long addr;
  153.     unsigned i, acc;
  154.     for (i=0; i<0xFFFF; i++)        // for all possible selectors
  155.         if (acc = lar(i))           // if a valid selector
  156.         {
  157.             addr = D16AbsAddress(MK_FP(i,0)); 
  158.             printf("%04X %06lX LAR=%02X LSL=%04X PL=%02X %s %s %s %s\n",
  159.                 i,                              // selector
  160.                 addr,                           // physical base addr
  161.                 acc,                            // access-rights byte
  162.                 lsl(i),                         // segment limit
  163.                 i & 3,                          // protection level
  164.                 verr(i) ? "VERR" : "    ",      // readable?
  165.                 verw(i) ? "VERW" : "    ",      // writeable?
  166.                 i & 4 ? "LDT" : "GDT",          // which table?
  167.                 i == addr >> 4 ? "TRANS" : ""); // transparent?
  168.         }
  169. }
  170.  
  171.  
  172. [LISTING FOUR]
  173.  
  174. /* SEL.C */
  175.  
  176. void sel(void far *fp)
  177. {
  178.     extern DESCRIPTOR far *gdt;
  179.     extern DESCRIPTOR far *ldt;
  180.     unsigned seg = FP_SEG(fp);
  181.     unsigned index = seg >> 3;  
  182.     DESCRIPTOR far *dt = (seg & 4) ? gdt : ldt; // table indicator
  183.     ACCESS_RIGHTS *pacc = (ACCESS_RIGHTS *) &dt[index].access;
  184.     printf("SEL=%04X ADDR=%02X%04X LIMIT=%04X ACCESS=%d%c%c%c%c%c%c\n",
  185.         seg, dt[index].addr_hi, dt[index].addr_lo, dt[index].limit,
  186.         // display access rights as if they were file attributes:
  187.         pacc->dpl,
  188.         pacc->accessed ? 'a' : '-',
  189.         pacc->read_write ? ((pacc->code_data) ? 'r' : 'w') : '-',
  190.         pacc->conf_exp ? ((pacc->code_data) ? 'f' : 'e') : '-',
  191.         pacc->code_data ? 'c' : 'd',
  192.         pacc->xsystem ? '-' : 's',
  193.         pacc->present ? 'p' : '-');
  194. }
  195.  
  196.  
  197. [FIGURE 1]
  198.  
  199.         # char *p;
  200.         # #include <malloc.h>
  201.         MALLOC.H included
  202.         # p = malloc(10240)
  203.             address 03B8:01A6: ""
  204.         # #include "dos16.h"
  205.         DOS16.H included
  206.         # D16AbsAddress(p)
  207.             2940246 (0x2CDD56)
  208.         # #include <dos.h>
  209.         DOS.H included
  210.         # int handle;
  211.         # _dos_open("\\msc\\inc\\dos.h", 0, &handle)
  212.             0
  213.         # handle
  214.             7
  215.         # unsigned bytes;
  216.         # _dos_read(handle, p, 10240, &bytes)
  217.             0
  218.         # bytes
  219.             5917 (0x171D)
  220.         # _dos_close(handle)
  221.             0
  222.         # printf("%s\n", p)     // display file
  223.  
  224.  
  225.  
  226. [FIGURE 2]
  227.  
  228.         # char *s;  // oops: forgot to initialize
  229.         # atoi(s)
  230.          ## 492: Invalid address 0AA8:4582 at __CATOX+000E      
  231.         # #reset
  232.  
  233.  
  234. [FIGURE 3]
  235.  
  236.         # char *p;
  237.         # p = malloc(2013)
  238.             address 03B8:01A6: ""
  239.         # p[2013] = 'x'
  240.             'x' (0x78)
  241.  
  242.  
  243. [FIGURE 4]
  244.  
  245.         # char *q;
  246.         # q = D16SegAbsolute(D16AbsAddress(p), 2013);
  247.             0C08:0000
  248.  
  249. [FIGURE 5]
  250.  
  251.         # q[2013]
  252.          ## 492: Invalid address 0BF8:002A in command line
  253.         # D16AbsAddress(p) == D16AbsAddress(q)
  254.             1
  255.         # D16SegLimit(p) == D16SegLimit(q)
  256.             0
  257.         # D16SegLimit(p)
  258.             24575 (0x5FFF)
  259.         # D16SegLimit(q)
  260.             2012 (0x7DC)
  261.  
  262. [FIGURE 6]
  263.  
  264.  
  265.         LSL  (load segment limit) -- fetch size of a segment
  266.         LAR  (load access rights) -- fetch access rights of segment
  267.         VERR (verify read) -- can segment be peeked?
  268.         VERW (verify write) -- can segment be poked?
  269.         SGDT (store GDT) -- fetch base address of GDT
  270.         SIDT (store IDT) -- fetch base addr of IDT
  271.         SLDT (store LDT) -- fetch selector to LDT
  272.  
  273.  
  274. [FIGURE 7]
  275.  
  276.         # char *p;
  277.         # p = D16MemAlloc(10240)
  278.             address 0C08:0000
  279.         # lsl(FP_SEG(p))
  280.             10239 (0x27FF)
  281.  
  282. [FIGURE 8]
  283.  
  284.         unsigned i;
  285.         for (i=0; i<0xFFFF; i++)      // for all possible selectors
  286.             if (lar(i))               // if a valid selector
  287.                 printf("%04X\n", i);  // print selector
  288.  
  289.  
  290. [FIGURE 9]
  291.  
  292.         0038 000000 LAR=93 LSL=FFFF PL=00 VERR VERW GDT
  293.         003C 000000 LAR=93 LSL=FFFF PL=00 VERR VERW LDT
  294.         0040 000400 LAR=93 LSL=0FFF PL=00 VERR VERW GDT TRANS
  295.         0044 000400 LAR=93 LSL=0FFF PL=00 VERR VERW LDT
  296.         0048 034FE0 LAR=93 LSL=FFFF PL=00 VERR VERW GDT
  297.         004C 034FE0 LAR=93 LSL=FFFF PL=00 VERR VERW LDT
  298.         0050 110010 LAR=93 LSL=200F PL=00 VERR VERW GDT
  299.         0054 110010 LAR=93 LSL=200F PL=00 VERR VERW LDT
  300.         0058 032050 LAR=81 LSL=0067 PL=00           GDT
  301.         005C 032050 LAR=81 LSL=0067 PL=00           LDT
  302.         0060 FA0000 LAR=93 LSL=FFFF PL=00 VERR VERW GDT
  303.         0064 FA0000 LAR=93 LSL=FFFF PL=00 VERR VERW LDT
  304.         0068 100010 LAR=82 LSL=FFF8 PL=00           GDT
  305.  
  306.  
  307. [FIGURE 10]
  308.  
  309.         for (i=0; i<0xFFFF; i++)
  310.             if (lar(i) && (i & 3))
  311.                 printf("%04X PL=%02X\n", i, i & 3);
  312.  
  313. [FIGURE 11]
  314.  
  315.         for (i=0; i<0xFFFF; i++)
  316.             if (lar(i) && (i == D16AbsAddress(MK_FP(i,0)) >> 4))
  317.                 printf("%04X ", i);
  318.  
  319.  
  320. [FIGURE 12]
  321.  
  322.         typedef struct {
  323.             unsigned      limit, lo;
  324.             unsigned char hi, reserved;
  325.             } GDTR;
  326.  
  327.  
  328. [FIGURE 13]
  329.  
  330.         # GDTR g;
  331.         # sgdt(&g)
  332.         # g
  333.            struct  at 2F1C {
  334.               limit = 65528 (0xFFF8);
  335.               lo = 16 (0x10);
  336.               hi = '\020' (0x10);
  337.               reserved = '\0';}
  338.  
  339.  
  340. [FIGURE 14]
  341.  
  342.         typedef struct {
  343.             unsigned      limit;    // size minus 1
  344.             unsigned      addr_lo;  // physical base addr - paragraph.byte
  345.             unsigned char addr_hi;  // physical base addr - megabyte
  346.             unsigned char access;   // see ACCESS_RIGHTS below
  347.             unsigned      reserved; // for 386 (32-bit)
  348.             } DESCRIPTOR;
  349.  
  350.  
  351. [FIGURE 15]
  352.  
  353.         # DESCRIPTOR *gdt;      // GDT is array of DESCRIPTOR
  354.         # gdt = D16SegAbsolute((long) MK_FP(g.hi, g.lo), g.limit + 1)
  355.             address 0C08:0000
  356.  
  357.  
  358. [FIGURE 16]
  359.  
  360.         # gdt[FP_SEG(gdt) >> 3]
  361.            struct  at 0C08:0C08 {
  362.               limit = 65527 (0xFFF7);
  363.               addr_lo = 16 (0x10);
  364.               addr_hi = '\020' (0x10);
  365.               access = 'Q' (0x91);
  366.               reserved = 0;}
  367.  
  368.  
  369. [FIGURE 17]
  370.  
  371.         typedef struct access {
  372.             unsigned accessed   : 1;  // has segment been accessed?
  373.             unsigned read_write : 1;  // if data 1=write; if code 1=read
  374.             unsigned conf_exp   : 1;  // expansion direction
  375.             unsigned code_data  : 1;  // 0 = data, 1 = code
  376.             unsigned xsystem    : 1;  // 0 = system descriptor
  377.             unsigned dpl        : 2;  // protection level: 0..3
  378.             unsigned present    : 1;  // is segment in memory?
  379.             } ACCESS_RIGHTS;
  380.  
  381.         # *((ACCESS_RIGHTS *) &gdt[FP_SEG(gdt) >> 3].access)
  382.            struct access at 0C08:0C0D {
  383.               accessed : 1 = 1;       // it's been used
  384.               read_write : 1 = 0;     // it's read-only
  385.               conf_exp : 1 = 0;       // it's not a stack
  386.               code_data : 1 = 0;      // it's data
  387.               xsystem : 1 = 1;        // it's not a system descriptor
  388.               dpl : 2 = 0;            // protection level 0
  389.               present : 1 = 1;}       // it's present in memory
  390.  
  391.  
  392.  
  393.